﻿using mozhi.smarterp.Finance.AccountsReceivables.Repositories;
using mozhi.smarterp.Finance.Enums;
using mozhi.smarterp.Finance.Receivables;
using Mozhi.Abp.Domain.AuthorCenter;
using Mozhi.Abp.Domain.BasicData;
using Mozhi.Abp.Domain.BasicData.Repositories;
using System;
using System.Threading.Tasks;
using Volo.Abp.Guids;

namespace mozhi.smarterp.Finance.AccountsReceivables.Services
{
    public class SaleReceivableManager : DocumentDomainService<SaleReceivable, Guid>
    {
        private ICustomerRepository _customerRepository;
        private ICurrencyRepository _currencyRepository;
        private IDepartmentRepository _departmentRepository;
        private IEmployeeRepository _employeeRepository;
        private IGuidGenerator _guidGenerator;
        private IProductRepository _productRepository;
        private IExpenseItemRepository _expenseItemRepository;
        private ITaxRateRepository _taxRateRepository;

        public SaleReceivableManager(ISaleReceivableRepository repository, INumberGeneratorRepository numberGeneratorRepository , ICustomerRepository cusomterRepository, ICurrencyRepository currencyRepository,IDepartmentRepository departmentRepository, 
            IEmployeeRepository employeeRepository, IGuidGenerator guidGenerator, IProductRepository productRepository, IExpenseItemRepository expenseItemRepository, ITaxRateRepository taxRateRepository) 
            : base(repository, numberGeneratorRepository, DocumentType.SaleReceivable)
        {
            _customerRepository = cusomterRepository;
            _currencyRepository = currencyRepository;
            _employeeRepository = employeeRepository;
            _departmentRepository = departmentRepository;
            _guidGenerator = guidGenerator;
            _productRepository = productRepository;
            _taxRateRepository = taxRateRepository;
            _expenseItemRepository = expenseItemRepository;
        }

        public async Task<SaleReceivable> GetAsync(Guid? id, DateTime date, DateTime dueDate, ReceivableDocumentType type, RecognitionModelType recognitionModel, Guid customerId,
            Guid currencyId, decimal exchangeRate , bool includeTax, Guid? salerDepartmentId, Guid? salePersonId, Guid? payemtnTermId, string comment)
        {
            var customer = await _customerRepository.GetAsync(customerId);

            var currency = await _currencyRepository.GetAsync(currencyId);

            if (currency != null)
                currency.SetExchangeRate(exchangeRate);

            var salerDepartment = salerDepartmentId.HasValue ? await _departmentRepository.GetAsync(salerDepartmentId.Value) : null;
            var salePerson = salePersonId.HasValue ? await _employeeRepository.GetAsync(salePersonId.Value) : null;

            SaleReceivable saleReceivable;

            if (id.HasValue)
            {
                saleReceivable = await _repository.GetAsync(id.Value);

                saleReceivable.Change(date, dueDate, type, recognitionModel, customer, currency, includeTax, salerDepartment, salePerson, payemtnTermId, comment);
            }
            else
            {
                var number = await GetNextNumberAsync();

                saleReceivable = new SaleReceivable(_guidGenerator.Create(), number, date, dueDate, type, recognitionModel, customer, currency, includeTax, salerDepartment, salePerson, payemtnTermId, comment);
            }

            return saleReceivable;
        }

        public async Task<SaleReceivableItem> GetItemAsync(Guid? id , Guid? productId, Guid? expenseItemId, decimal basicQuantity, decimal price, decimal? amountFr, Guid? taxRateId, string remark)
        {
            var product = productId.HasValue ? await _productRepository.GetAsync(productId.Value) : null;
            var expenseItem = expenseItemId.HasValue ? await _expenseItemRepository.GetAsync(expenseItemId.Value) : null;
            var taxRate = taxRateId.HasValue ? await _taxRateRepository.GetAsync(taxRateId.Value) : null;
        
            id = id ?? _guidGenerator.Create();

            return new SaleReceivableItem(id.Value, product, expenseItem, basicQuantity, price, amountFr, taxRate, remark);

        }
    }
}
